package com.vadmin.vadminjava.service;


import com.alibaba.fastjson.JSONObject;
import com.ijpay.wxpay.WxPayApi;
import com.vadmin.vadminjava.common.*;
import com.vadmin.vadminjava.db.DBUtil;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;

import static com.ijpay.core.enums.RequestMethod.GET;
import static com.ijpay.core.enums.RequestMethod.POST;
import static com.ijpay.wxpay.enums.WxApiType.*;
import static com.ijpay.wxpay.enums.WxDomain.CHINA;
import static com.vadmin.vadminjava.common.CommonUtils.mapToJSONObject;
import static com.vadmin.vadminjava.common.WxCouponUtils.MCH_ID;
import static com.vadmin.vadminjava.common.WxCouponUtils.SERIAL_NO;

/* ***********************************************************
 *
 * 微信的卡劵：后台管理专用的
 *
 * **********************************************************/
@Component
public class WxCouponAdminService extends CommonExtends{
    org.slf4j.Logger logger = LoggerFactory.getLogger(WxCouponCashService.class.getName());

    @Autowired
    WxCouponUtils wxCouponUtils;
    @Autowired
    WxCouponBusinessService wxCouponBusinessService;
    @Autowired
    AdminLogService adminLogService;
    @Autowired
    WxUserMoneyService wxUserMoneyService;

    /**
     * 商家券列表
     * @param params
     * @return
     */
    public JSONObject wxCouponBusinessList(JSONObject params) {

        String table  = "wx_coupon";//数据库表
        String conditions = "";//条件

        //参数处理
        //String  transactionMinimum = params.getString("transactionMinimum");
        //if(StringUtils.isNoneEmpty(transactionMinimum)){
        //    conditions += " AND transaction_minimum >= '" + transactionMinimum + "' ";
        //}

        return commonDataListFlexible(table,conditions,params);
    }

    /**
     * 客户已领取的商家券
     * @param params
     * @return
     */
    public JSONObject couponListOfBusinessFetched(JSONObject params){


        String table  = "wx_coupon_user";//数据库表
        String conditions = "";//条件

        //参数处理
        //String  transactionMinimum = params.getString("transactionMinimum");
        //if(StringUtils.isNoneEmpty(transactionMinimum)){
        //    conditions += " AND transaction_minimum >= '" + transactionMinimum + "' ";
        //}

        return commonDataListFlexible(table,conditions,params);
    }

    /**
     *  //todo 他妈的这里返回签名错误******************************************************************************************
     *  从微信服务器读取当前商家券回调url
     *  使用微信demo类
     * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter9_2_8.shtml
     */
    public JSONObject getCallbackUrlOfCouponBusiness(JSONObject params) {
        //初始化
        JSONObject map    = new JSONObject();
        map.put("resultFlag",false);
        map.put("resultMsg","操作失败");

        JSONObject query = new JSONObject();
        query.put("mchid",MCH_ID);
        String requestJson = query.toJSONString();
        try {
            Map<String, Object> stringObjectMap = WxPayApi.v3Execution(
                    GET,
                    CHINA.toString(),
                    BUSINESS_COUPON_CALLBACKS.toString(),
                    MCH_ID,
                    SERIAL_NO,
                    wxCouponUtils.KEY_PATH,
                    requestJson
            );

            System.out.println("读取>>>>>回调url微信返回原始数据："+ stringObjectMap);
        } catch (Exception ex) {

        }

        return map;
    }


    /**
     *  从微信服务器读取当前商家券回调url
     * 用这get直接请求，会报什么蓝交Authorization头错误
     * @param params
     * @return
     */
    public JSONObject getCallbackUrlOfCouponBusiness2(JSONObject params) {
        //初始化
        JSONObject map    = new JSONObject();
        map.put("resultFlag",false);
        map.put("resultMsg","操作失败");

        //这个方式会返回：{"code":"INVALID_REQUEST","message":"Http头缺少Accept或User-Agent"}
        //String url = "https://api.mch.weixin.qq.com/v3/marketing/busifavor/callbacks?mchid=" + MCH_ID;
        //String response = doGet(url);

        String host = "https://api.mch.weixin.qq.com";
        String path = "/v3/marketing/busifavor/callbacks";
        Map<String, String> query = new HashMap<>();
        query.put("mchid",MCH_ID);

        Map<String, String> headers = new HashMap<>();
        headers.put("Accept","*/*");
        headers.put("User-Agent","Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)");
        try {
            String response = HttpUtils.doGet2(host,path,headers,query);

            System.out.println(response);
        } catch (Exception ex) {
        }

        return map;
    }

    /**
     * 设置商家券回调url
     * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter9_2_7.shtml
     * @param params
     * @return
     */
    public JSONObject setCallbackUrlOfCouponBusines(JSONObject params){
        //初始化
        JSONObject map    = new JSONObject();
        map.put("resultFlag",false);
        map.put("resultMsg","操作失败");

        String notifyUrl = params.getString("url");//参数

        JSONObject data = new JSONObject();

        //组织请求数据json字符
        JSONObject query = new JSONObject();
        query.put("mchid",MCH_ID);
        query.put("notify_url",notifyUrl);
        String requestJson = query.toJSONString();

        try {
            //{serialNumber=201D85E3CB2B2D9E99C937C12E736DA049209D77, body={"mchid":"1622221291","notify_url":"https://www.qzzhuoen.com/couponServlet/conpuonCallback","update_time":"2022-04-14T15:50:06+08:00"}, signature=SRg4w/RXzpVqDFx09O6YLi7Um/5NfUHJg48Q9b78nqAF9dNqXO0urqIVUKU1aVp6Z4RtqvVpADOQeS9+JQgpXgkBpi8/3OwJAyWj3Ra9WtbnREe/xsbZgLMe2vVsQMuXAn9RKhbyF3kY+57fKE65vvvclKHiuPdGi4fyRlKistPu6AECWGt9N4P+n6bKujRexuHMj4PdL8RhfkuyuSfJr0VQQtWU5ouv/MRViZuUo3aLA2yAETygi3LbNU+rYpvVHbkb7WGowYniC1TXluJPQeHwE3/Ln36Iow3p5Ug1jv7lGDeqJ3sJX4ovBe39IS8bWEvqA2ArU8b33ehxUqzA+Q==, nonceStr=56a677b1b0a7d0e7e15c4a2edd7197b7, timestamp=1649922606, status=200}
            Map<String, Object> stringObjectMap = WxPayApi.v3Execution(
                    POST,
                    CHINA.toString(),
                    BUSINESS_COUPON_CALLBACKS.toString(),
                    MCH_ID,
                    SERIAL_NO,
                    wxCouponUtils.KEY_PATH,
                    requestJson
            );
            data = mapToJSONObject(stringObjectMap);
            logger.info("设置>>>>>回调url微信返回原始数据："+ stringObjectMap);
            logger.info("设置>>>>>回调url微信返回原始数据JSON："+ data);

            if(data.getString("status").equals("200")){
                map.put("resultFlag",true);
                map.put("resultMsg","操作成功");
                map.put("data",data);
            }else{
                map.put("data",data);
                map.put("resultFlag",false);
                map.put("resultMsg","操作失败，状态码是");
            }

        } catch (Exception ex) {
            logger.error("设置商家券回调url出错了：{}",ex);
        }

        return map;
    }


    //商家券核主入口调遣
    public JSONObject useCouponBusinessAdminDispatch(JSONObject params){

        //初始化
        JSONObject map    = new JSONObject();
        map.put("resultFlag",false);
        map.put("resultMsg","操作失败");
        Map<String, Object> response = new HashMap<>();
        String log = "";
        Boolean _processingStatus = false;//数据库处理结果，默认失败

        //参数
        String _couponId = params.getString("couponId");
        String _couponCode = params.getString("couponCode");
        String _openId = params.getString("openId");

        // 这个值可以随意创建，只要保证唯一即可（不用在意我的创建方法）
        // 商户创建批次凭据号（格式：商户id+日期+流水号），可包含英文字母，数字，|，_，*，-等内容，不允许出现其他不合法符号，商户侧需保持唯一性 (9856886520200811174644kk6tclE)
        String outRequestNo  = System.currentTimeMillis() + ThreadLocalRandom.current().nextInt(100000) + "";
        params.put("outRequestNo",outRequestNo);

        //执行
        //首次{serialNumber=201D85E3CB2B2D9E99C937C12E736DA049209D77, body={"openid":"oqGpx6O8tX3tTAEx0SyzfTVS0d_Q","stock_id":"1210840000000013","wechatpay_use_time":"2022-04-05T15:15:44+08:00"}, signature=pVpp2uGGukw0l60y+yBSE0EPvoPgLskcFU1F4CPbzTLAKZ9GqpIctu19sYaQPlfb/nkzrVePGDXZpx1zlpFimOHvMZzF+GmHQ0iwdFuYgyaSozlo0PVOivHomj2Fx4YOajdfHqebtf3e4ZK7Q6+N2av48e64+FJnUD7DA5m/a+B1UPvVHSgbqgqRgYQTdLld3uC6akDb9s9iDelK2kzElVsfhjewpTpcL2Ab+3KqOhBM7vpdLSHvK4HD9U7NKEnNrgyGOLSPP1TJt6iweFH+095tSDvvOFEq54MTDDRmN4rmmnv7kvxpSVG6GcsX/Qk7m1AWqt5Hqm8dy/hUwr1hBg==, nonceStr=7ad2eb31fbb3da9de8837bb6cfe939a6, timestamp=1649142944, status=200}
        //重复{serialNumber=201D85E3CB2B2D9E99C937C12E736DA049209D77, body={"code":"RESOURCE_ALREADY_EXISTS","message":"券已被其他订单核销"}, signature=HGRDmL0ntntyrXG6U+1eCfr3JHgiIr8imoAAut1wdGBiV+L30atc2sJPD3p9fI8fvlzPLp+mORVXpnUfFlbQhDPcGzzDN/oS2FbucmJVxptK0KBbKOQD0HaZr+a8GBqfnYcdePbyLUTMHUek46/rEKoKMtRIHT2CVLy1CF1oZmr9nmbT/udRk+TiMPqqHBPDhBzijdInbjJiXs9iNHJr9TaoaHQr8fNQwFTJtF2PIFzggf3elVE1jMUc6syBEzIiRJIBsA3UBk5XphM4zHn1VoMNWq94G+3tii5Hu2TpMK5Ld8JL4UcAO2bg9wC7CZp/PAm69jaiet5066Kor9ykRQ==, nonceStr=f8865d54acc2a4a1185966ee480fb7ac, timestamp=1649143837, status=400}
        response = wxCouponBusinessService.useCouponBusinessToWeixinServer(params);
        JSONObject responseJSONObject = mapToJSONObject(response);
        JSONObject responseBody = responseJSONObject.getJSONObject("body");//得到body部分，里面有code
        //System.out.println("转为jsonobject"+responseJSONObject);

        //注意，返回的有状态码的状态文本
        String responseStatus = responseJSONObject.getString("status");//状态值
        String responseCode = responseBody.getString("code");//状态文本



        //这里要先记录log
        log = log + "用户"+_openId+"核销了卡券"+_couponId+"，券码是"+_couponCode;
        String responseString = response.toString().replaceAll("[{}]","");



        //根据状态码处理
        if(responseStatus.equals("200")){//成功
            String _useProcessingResponse = "并且数据处理成功";//自定义处理结果

            useCouponBusinessAdminProcess(_openId,_couponId,_couponCode);

            map.put("resultFlag",true);
            map.put("resultMsg","操作成功，" + _useProcessingResponse);

        }else if(responseStatus.equals("400")){
            map.put("resultFlag",false);
            map.put("resultMsg","操作失败,状态码是400，状态文本是:"+responseCode);

            //dev

        }


        logger.info(log + ">>>>返回数据：" + response.toString());
        adminLogService.write(LogEnum.COUPON_USE.name,LogEnum.COUPON_USE.index,"核销卡券："+log+">>>>返回信息：" + responseString);

        return map;
    }

    /**
     * 核销的相关数据处理
     * 2022-04-06 初次开发测试完
     * @param openId
     * @param couponId
     * @param couponCode
     * @return
     */
    public Boolean useCouponBusinessAdminProcess(String openId,String couponId,String couponCode){
        Boolean ret = false;
        String log = "";
        DBUtil dbUtil = new DBUtil();
        try {
            dbUtil.conn.setAutoCommit(false);

            //↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 佣金处理 类型码已校验↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
            //先查看这券有没有进行相关事件的分佣（核销）
            String sqlC = "select count(id) as count1 from wxwork_user_money_log " +
                    "where coupon_code='"+couponCode+"' and open_id ='"+openId+"' and event_code = '"+ MoneyLogEnum.COUPON_USE.code+"'";
            Integer count = ResultSetToJavaBean.copyJsonSingleQuery(dbUtil,sqlC).getInteger("count1");

            if(count==0){//没有分过就进行处理

                //更新用户券的状态
                String sql1 = "update wx_coupon_user set use_status = 1 where open_id='"+openId+"' and coupon_id = '"+couponId+"' and coupon_code='"+couponCode+"'";
                //System.out.println("更新用户券的状态"+sql1);
                dbUtil.insertOrUpdateInfoTONum(sql1);

                //找到这个openid的外部客户的所属员工(可能有多个员工,应该是最早的那个)
                // 以关系表为准
                String sql3 = "SELECT wr.userid,wr.external_userid,wur.open_id " +
                        " from wxwork_relation wr " +
                        " LEFT JOIN wx_user_relation wur " +
                        " on wur.external_userid = wr.external_userid " +
                        " where wur.open_id = '"+openId+"'";
                JSONObject rs = ResultSetToJavaBean.copyJsonSingleQuery(dbUtil,sql3);//得到单个记录集
                String _referrer = rs.getString("userid");
                String _externalUserid = rs.getString("externalUserid");
                String _amount = WxWorkConfig.COMMISSION_USE.toString();//操作资金数

                //找到员工的资金数据，进行计算
                String sql4 = "select * from wxwork_user where user_id = '" + _referrer + "'";
                Double _money = ResultSetToJavaBean.copyJsonSingleQuery(dbUtil, sql4).getDouble("money");
                String _moneyAfter = BigDecimalUtils.add(_money,_amount).toString();

                //在这个位置更新员工资金
                wxUserMoneyService.userMoneyChange(dbUtil,_referrer,_amount);

                //记录明细
                JSONObject logParams = new JSONObject();
                logParams.put("user_id",_referrer);
                logParams.put("external_userid",_externalUserid);
                logParams.put("open_id",openId);
                logParams.put("money_before",_money);
                logParams.put("money",_amount);
                logParams.put("money_after",_moneyAfter);
                logParams.put("coupon_id",couponId);//
                logParams.put("coupon_code",couponCode);
                logParams.put("event",     MoneyLogEnum.COUPON_USE.name);
                logParams.put("event_code",MoneyLogEnum.COUPON_USE.code);
                logParams.put("type",      MoneyLogEnum.TYPE_ADD.name);
                logParams.put("type_code", MoneyLogEnum.TYPE_ADD.code);
                logParams.put("remark","进行了券的核销分佣");
                wxUserMoneyService.userMoneyLog(dbUtil,logParams);//写入

                log = "核销了用户"+openId+"券"+couponId+"，券码是"+couponCode+"，进行分佣处理>>";
                logger.info(log);

            }else{
                log = "进行核销用户"+openId+"券"+couponId+"，券码是："+couponCode+"，但已经存在这个券的核销分佣，不重复分佣。";
                logger.info(log);
            }


            dbUtil.conn.commit();
            ret = true;

        } catch (Exception ex) {
            ret = false;
            logger.error("核销的相关数据处理出错了：{}",ex);
        } finally {
            dbUtil.closeNoErr();
        }

        return ret;
    }


    //卡券详情（用于核销的，塞入了其它东西）
    public JSONObject couponDetailForUse(JSONObject params){
        //初始化
        DBUtil dbUtil = new DBUtil();
        JSONObject map    = new JSONObject();
        map.put("resultFlag",false);
        map.put("resultMsg","操作失败");

        String _couponCode = params.getString("couponCode");

        try {
            //找出具体券码的券id,领取人
            String sql = "";
            sql = sql + " select wcu.*,wc.*,wur.external_userid,weu.* from wx_coupon_user wcu";
            sql = sql + " left join wx_coupon wc on wc.stock_id = wcu.coupon_id";
            sql = sql + " left join wx_user_relation wur on wur.open_id = wcu.open_id";
            sql = sql + " left join wxwork_external_user weu on weu.external_userid = wur.external_userid";
            sql = sql + " where wcu.coupon_code = '"+_couponCode+"';";

            JSONObject couponUser = ResultSetToJavaBean.copyJsonSingleQuery(dbUtil,sql);
            System.out.println(sql);
            //System.out.println(couponUser);

            map.put("data",couponUser);
            map.put("resultFlag",true);
            map.put("resultMsg","操作成功");

        } catch (Exception ex) {

        } finally {
            dbUtil.closeNoErr();
        }
        return map;
    }

}
